#!/usr/bin/python3
# -*- coding: utf-8 -*
"""
Description: A client that control data acquiring and data parsing.
Class: ParserClient,FMAParserClient.
"""
import gc

from ..libs.log import LOGGER
from ..libs.time_utils import print_run_time


class ParserClient():
    """
    class ParserClient is the controller which can get data from datasource,
    and parse the data using parsers.
    """

    def __init__(self, datasource=None, param_config=None, regex_config=None, parsers=None):
        """
        Class instance initialization.

        Args:
            regex_config_file (str): the path to regex configuration file.
            datasource (object): an object that keeps the log configuration and log content.
        """
        # single raw data
        self.data = []
        # formatted data
        self.result = []
        self.datasource = datasource
        self.param_config = param_config
        self.regex_config = regex_config
        self.parsers = parsers

    def clear(self):
        """
        Release memory.

        Args:

        Returns:
        """
        del self.data
        del self.result
        gc.collect()
        self.data = []
        self.result = []

    @print_run_time
    def get_data(self, **kwargs):
        """
        Get data from datasource.

        Args:
            check_types (list):
            time_range (list):

        Returns:
        """
        if self.datasource is None:
            LOGGER.error("No datasource.")
            return

        if self.param_config is None:
            self.param_config = self.datasource.param_config

        self.data = self.datasource.read_all_data(**kwargs)

    @print_run_time
    def get_parsed_content(self):
        """
        parse the data according to related parser, then store into Spec.

        Args:

        Returns:
        """
        for spec in self.data:
            key = spec.symbolic_name
            log_type = self.param_config[key].get('log_type')
            # without log_type or content
            if not all([log_type, spec.content]):
                spec.res = spec.content
                spec.parse_flag = False
                self.result.append(spec)
                continue
            # Type of the log_type should be list.
            if not isinstance(log_type, list):
                log_type = [log_type]
                self.param_config[key]['log_type'] = log_type
            spec.file_type = log_type
            # items with "head" means it's a mixinfo data.
            if self.param_config[key].get('head') is not None:
                parser = self.parsers.get('mixinfo')
            elif log_type == ['content']:
                spec.res = spec.content
                spec.parse_flag = True
                self.result.append(spec)
                continue
            else:
                parser = self.parsers.get(log_type[0])
            # call the parser function
            if parser is not None:
                spec.res, success = parser(self.param_config[key], self.regex_config).parse_content(
                    key, spec.content)
            else:
                LOGGER.error("There is no matched parser for '%s' of '%s', please check again.",
                             key, log_type)
                success = False
                spec.res = spec.content
            spec.parse_flag = success
            self.result.append(spec)
